<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>服务</title>
    <link rel="stylesheet" href="../lib/bootstrap3/css/bootstrap.min.css">
    <link rel="stylesheet" href="../lib/bootstrap3/css/dashboard.css">
    <script src="../lib/angularjs/angular.min.js"></script>
</head>
<body ng-app="app">
<div class="well">
    <h3 class="alert alert-danger">注册服务的方式</h3>
    <p class="alert alert-warning">
        Factory/service是第一个注入时才实例化，而provider不是，它是在config之前就已实例化好了
    </p>
    <div style="width:550px">
        <ul class="list-group">
            <li class="list-group-item">
                <span class="badge">参数：（服务名，实例函数）</span>factory
            </li>
            <li class="list-group-item list-group-item-success ">
                <span class="badge">service</span>service
            </li>
            <li class="list-group-item">
                <span class="badge">constant</span>constant
            </li>
            <li class="list-group-item">
                <span class="badge">value</span>value
            </li>
            <li class="list-group-item">
                <span class="badge">provider</span>provider
            </li>
        </ul>
    </div>
    <ul class="nav nav-pills" role="tablist">
        <li role="presentation" class="active"><a href="#">factory <span class="badge">参数：（服务名，实例函数）</span></a></li>
        <li role="presentation" class="active"><a href="#">service()<span class="badge">service</span></a></li>
        <li role="presentation" class="active"><a href="#">constant <span class="badge">constant</span></a></li>
        <li role="presentation" class="active"><a href="#">value <span class="badge">value</span></a></li>
        <li role="presentation" class="active"><a href="#">provider <span class="badge">provider</span></a></li>
    </ul>
</div>
<div class="well" ng-controller="ctrl01">
    <h3 class="alert alert-danger">通过factory创建服务</h3>
    <p class="alert alert-warning">
        它是一个可注入的function，它和service的区别就是：factory是普通function，而service是一个构造器(constructor)，这样Angular在调用service时会用new关键字，
        而调用factory时只是调用普通的function，所以factory可以返回任何东西，而service可以不返回(可查阅new关键字的作用)
    </p>
    <p>
        <button class="btn btn-success" ng-click="getUser()">点击</button>
    </p>
    当前登录用户：{{user}}
</div>
<div class="well" ng-controller="ctrl02">
    <h3 class="alert alert-danger">通过service创建服务</h3>
    <p class="alert alert-warning">
        它是一个可注入的构造器，在AngularJS中它是单例的，用它在Controller中通信或者共享数据都很合适
    </p>
    <p>
        <button class="btn btn-success" ng-click="getVariable()">得到一个变量</button>&nbsp;&nbsp;{{variable}}<br/>
    </p>
    <p>
        <button class="btn btn-success" ng-click="generateValue()">随机生成一个值</button>&nbsp;&nbsp;{{generate}}
    </p>
</div>
<div class="well" ng-controller="ctrl03">
    <h3 class="alert alert-danger">通过provider创建服务</h3>
    <p class="alert alert-warning">
        provider是他们的老大，上面的几乎(除了constant)都是provider的封装，provider必须有一个$get方法，当然也可以说provider是一个可配置的factory
    </p>
    <p>
        <button class="btn btn-success" ng-click="getVariable()">得到一个变量</button>&nbsp;&nbsp;{{variable}}<br/>
    </p>
    <p>
        <button class="btn btn-success" ng-click="generateValue()">随机生成一个值</button>&nbsp;&nbsp;{{generate}}
    </p>
</div>
<div class="well" ng-controller="ctrl04">
    <h3 class="alert alert-danger">constant</h3>
    <p class="alert alert-warning">
        定义常量用的，这货定义的值当然就不能被改变，它可以被注入到任何地方，但是不能被装饰器(decorator)装饰
    </p>
    <h2>{{flag}}</h2>
</div>
<div class="well" ng-controller="ctrl05">
    <h3 class="alert alert-danger">Value</h3>
    <p class="alert alert-warning">
        这货可以是string,number甚至function,它和constant的不同之处在于，它可以被修改，不能被注入到config中，但是它可以被decorator装饰
    </p>
    <h2>{{message}}</h2>
</div>
<div class="well" ng-controller="ctrl06">
    <h3 class="alert alert-danger">Constant</h3>
    <p class="alert alert-warning">
        这个比较特殊，它不是provider,它是用来装饰其他provider的，而前面也说过，他不能装饰Constant，因为实际上Constant不是通过provider()方法创建的。
    </p>
    <p>
        {{movieTitle}}
    </p>
</div>
</body>
<script>
    var app=angular.module('app',[]);
</script>
<script>
    app.factory('UserService',function ($http) {
        var loginUser;
        var that=this;
        return {
            getUserById:function (id) {
                $http.get("../7.3.json").then(function (response) {
                    loginUser= response.data;
                });
            },
            setUser:function (user) {
                loginUser=user;
                return loginUser;
            },
            getUser:function () {
                return loginUser;
            }
        }
    });
    app.controller('ctrl01',function ($scope,UserService) {
       $scope.user=null;
        $scope.user=UserService.setUser(123);
        UserService.getUserById(123);
        $scope.getUser=function () {
            $scope.user=UserService.getUser();
        }
    });
</script>
<script>
    app.service('VarService',function () {
        this.variable="Hello Word !";
        this.generateValue=function () {
            return (Math.random()*100).toFixed(2);
        }
    });
    app.controller('ctrl02',function ($scope,VarService) {
        $scope.getVariable=function () {
            $scope.variable=VarService.variable;
        };
        $scope.generate=VarService.generateValue();
        $scope.generateValue=function () {
            $scope.generate=VarService.generateValue();
        }
    });
</script>
<script>
    app.provider('VarService3',{
        $get:function () {
            return {
                'variable':'Hello Word !',
                'generateValue':function () {
                    return (Math.random()*100).toFixed(2);
                }
            }
        }
    });
    app.config(function($provide) {
        $provide.provider('greeting', function() {
            this.$get = function() {
                return function(name) {
                    return ("Hello," + name);
                };
            };
        });
    });
    app.controller('ctrl03',function ($scope,VarService3,greeting) {
        $scope.getVariable=function () {
            $scope.variable=VarService3.variable;
        };
        $scope.generateValue=function () {
            $scope.generate=VarService3.generateValue();
        }
        $scope.variable=greeting(123);
    });
</script>
<script>
    app.config(function ($provide) {
        $provide.constant('movieTitle', 'The Matrix');
    });

    app.controller('ctrl04', function ($scope,movieTitle) {
        $scope.flag=movieTitle==('The Matrix');
    });
</script>
<script>
    app.config(function ($provide) {
        $provide.value('movieTitle5', 'The Matrix')
    });

    app.controller('ctrl05', function ($scope,movieTitle5) {
        $scope.message=(movieTitle5)==('The Matrix');
    })
</script>
<script>
    app.value('movieTitle', 'The Matrix');

    app.config(function ($provide) {
        $provide.decorator('movieTitle', function ($delegate) {
            return $delegate + ' - starring Keanu Reeves';
        });
    });

    app.controller('ctrl06', function (movieTitle) {
        expect(movieTitle).toEqual('The Matrix - starring Keanu Reeves');
    });
</script>
</html>